package com.geoboard;


import org.codehaus.jackson.type.TypeReference;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.widget.EditText;
import android.widget.Toast;

import com.android.volley.Request.Method;
import com.geoboard.application.GeoBoardApplication;
import com.geoboard.dialogs.ErrorDialogFragment;
import com.geoboard.entity.Board;
import com.geoboard.entity.User;
import com.geoboard.fragments.BoardContainer;
import com.geoboard.fragments.MapFrag;
import com.geoboard.fragments.PostsContainer;
import com.geoboard.service.PostUserErrorListener;
import com.geoboard.service.PostUserListener;
import com.geoboard.tools.JacksonRequest;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;

public class MainActivity extends FragmentActivity 
			implements ActivityInterface, 
			GooglePlayServicesClient.ConnectionCallbacks,
			GooglePlayServicesClient.OnConnectionFailedListener {
	
	/**** Members *************************************************/
	private LocationClient mLocationClient;
	private MapFrag mMapFrag;
	private BoardContainer mBoardContainer; 
	private PostsContainer mPostsContainer;
	
	private final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;

	/**** Android Callback Methods *********************************/
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        
        
        setContentView(R.layout.activity_main);
        
		if (servicesConnected())
			mLocationClient = new LocationClient(this, this, this);
		
		//init Volley
		HelperVolley.init(this);
		
		//get username
		getPreferences();
		
		//add map
        mMapFrag = new MapFrag();   
        getSupportFragmentManager().beginTransaction().add(R.id.map_container, mMapFrag).commit();
        
        //add board overlay
        mBoardContainer = new BoardContainer();
        getSupportFragmentManager().beginTransaction().add(R.id.overlay_container, mBoardContainer).commit();
    }

	@Override
	public void onStart(){
    	super.onStart();
    	mLocationClient.connect();
    }
    
    @Override
    public void onStop() {
        mLocationClient.disconnect();
        super.onStop();
    }    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
    /**** GooglePlay Callback Methods **************************************************************/
    
     // Handle results returned to the FragmentActivity by Google Play services
    @Override
    protected void onActivityResult(
            int requestCode, int resultCode, Intent data) {
        // Decide what to do based on the original request code
        switch (requestCode) {
            case CONNECTION_FAILURE_RESOLUTION_REQUEST:
            /*
             * If the result code is Activity.RESULT_OK, try
             * to connect again
             */
                switch (resultCode) {
                    case Activity.RESULT_OK :
                    /*
                     * Try the request again
                     */
                    break;
                }
                
             //TODO incomplete copied from http://developer.android.com/training/location/retrieve-current.html
        }
     }
    
    /*
     * Called by Location Services when the request to connect the
     * client finishes successfully.
     */
    @Override
    public void onConnected(Bundle dataBundle) {
    	Location userLocation = mLocationClient.getLastLocation();
    	mMapFrag.animateCamera(userLocation);
    }
    
    /*
     * Called by Location Services if the connection to the
     * location client drops because of an error.
     */
    @Override
    public void onDisconnected() {
        // Display the connection status
        Toast.makeText(this, "Disconnected. Please re-connect.",
                Toast.LENGTH_SHORT).show();
    }
    
    /*
     * Called by Location Services if the attempt to
     * Location Services fails.
     */
    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        /*
         * Google Play services can resolve some errors it detects.
         * If the error has a resolution, try sending an Intent to
         * start a Google Play services activity that can resolve
         * error.
         */
        if (connectionResult.hasResolution()) {
            try {
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(
                        this,
                        CONNECTION_FAILURE_RESOLUTION_REQUEST);
            /*
             * Thrown if Google Play services canceled the original
             * PendingIntent
             */
            } catch (IntentSender.SendIntentException e) {
                // Log the error
                e.printStackTrace();
            }
        } else {
           Toast.makeText(this, "Unable to obtain location", Toast.LENGTH_SHORT).show();
        }
    }
    
    /**** Methods ********************************************************/
    
    private void getPreferences() {
    	SharedPreferences sharedPref = getPreferences(MODE_PRIVATE);
    	String userName = sharedPref.getString("com.geoboard.entity.user.name", null);
    	String id = sharedPref.getString("com.geoboard.entity.user.id", null);
    	User user = new User(userName, id);
    	//enter create user process
    	if (userName == null || id == null) {
    		createUser();
    	} else {
    		GeoBoardApplication.setUser(user);
    	}
    }
    
  private void createUser() {
	  	AlertDialog.Builder alert = new AlertDialog.Builder(this);

    	alert.setTitle("Welcome to Geoboard!");
    	alert.setMessage("Enter a user name");
    	final Activity context = this;

    	// Set an EditText view to get user input 
    	final EditText input = new EditText(this);
    	alert.setView(input);

    	alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
    	public void onClick(DialogInterface dialog, int whichButton) {
    		String username = input.getText().toString();
			JacksonRequest<User> request = new JacksonRequest<User>(
									Method.POST,
									GeoBoardApplication.USER_URL + "?" + "name=" + username,
									null,
									new TypeReference<User>(){},
									new PostUserListener(context), 
									new PostUserErrorListener(context));
			request.setShouldCache(false);
			HelperVolley.getRequestQueue().add(request);
			
			Toast.makeText(context, "Sending request", Toast.LENGTH_SHORT).show();
    	  }
	});

	alert.show();
}

    private boolean servicesConnected() {
        int resultCode =
                GooglePlayServicesUtil.
                        isGooglePlayServicesAvailable(this);
        // If Google Play services is available
        if (ConnectionResult.SUCCESS == resultCode) {
            return true;
        } else {
            // Get the error dialog from Google Play services
            Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
                    resultCode,
                    this,
                    CONNECTION_FAILURE_RESOLUTION_REQUEST);

            // If Google Play services can provide an error dialog
            if (errorDialog != null) {
                // Create a new DialogFragment for the error dialog
                ErrorDialogFragment errorFragment =
                        new ErrorDialogFragment();
                // Set the dialog in the DialogFragment
                errorFragment.setDialog(errorDialog);
                // Show the error dialog in the DialogFragment
                errorFragment.show(getSupportFragmentManager(),
                        "Location Updates");
            }
            return false;
        }
    }

    /**** ActivityInterface handlers *********************************************/
	
	@Override
	public void showPosts(Board board){
        //switch to post overlay
        mPostsContainer = new PostsContainer();
        Bundle args = new Bundle();
        args.putParcelable("com.GeoBoard.entity.board", board);
        mPostsContainer.setArguments(args);
        getSupportFragmentManager()
        	.beginTransaction()
        		.addToBackStack(null)
        		.replace(R.id.overlay_container, mPostsContainer)
        		.commit();
	}

	@Override
	public MapFrag getMapFrag() {
		return mMapFrag;
	}
}
